實作簡單的REST API


Posted by Nacho on 2020-03-29

實作目標

寫一個簡單的Web Server,處裡不同HTTP動作的請求,並輸出字串回應。

開始

在Go的工作目錄底下,建立一個新資料夾叫 SimpleRESTAPI,並建立一個主程式的執行檔 main.go。基本的檔案內容如下,這裡需要引入net套件中的http函式庫,後續才能用Go產生一個 http server。

package main

import(
    "fmt"
    "net/http"
)

func main() {
}

階段一: 建立一個 web server

撰寫一個notFound的處裡器,讓 server 啟動後可以顯示一點東西。在這個notFound函式會傳入兩個參數。先從第二個參數說起 ,r 代表Request負責接收client端發出的請求,並交由第一個參數 w 負責為請求做出回應與寫入訊息。針對寫入的訊息,在函式內可以設定了http的表頭、狀態及內容。

func notFound(w http.ResponseWriter, r *http.Request){
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusNotFound)  
    w.Write([]byte(`{"message": "not found"}`)) // 傳輸 []byte 格式的資料
}

func main() {
    http.HandleFunc("/", notFound) // 指定任何路徑下的都去呼叫 notFound 函式
    http.ListenAndServe(":8000", nil) // 指定server監聽 port 8000 
}

這裡加上例外處裡顯示像是port號已被其它程式占用或其他的錯誤訊息。

func main() {
    http.HandleFunc("/", notFound) 
    err := http.ListenAndServe(":8000", nil)
    if err != nil {
        panic(err) // 如果有錯誤就終止程式
    }
    fmt.Println("The port 8000 is successfully connected")
}

階段二: 建立路由功能

雖然使用 net/http 可以實現路由功能,但日後若有更多功能要開發,這樣的設計方式會衍伸路由管理的麻煩,因此這個階段導入了一個路由設計的套件叫gorilla/mux。可以用這行指令$ go get -u github.com/gorilla/mux取得這個套件。

import(
    "net/http"
    "github.com/gorilla/mux"
)
func get(w http.ResponseWriter, r *http.Request){
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK) 
    w.Write([]byte(`{"message": "get called"}`))
}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", get).Methods(http.MethodGet)
    err := http.ListenAndServe(":8000", router)
    if err != nil {
        panic(err) // 如果有錯誤就終止程式
    }
    fmt.Println("The port 8000 is successfully connected")
}

引入"github.com/gorilla/mux" ,這裡我註冊了一條新url路徑並指給 get 處裡,註冊新 url的方式與 http.HandleFunc()一樣,若有符合路徑的請求就到對應的處裡器並傳入參數(http.ResponseWriter, *http.Request)。參考文件 另外,這裡在HandleFunc()之後綁定 HTTP的動作,所以同一個路徑會針對有不同HTTP動作執行相對應的處裡器。現在可以打開終端機,先輸入go run main.go啟動go主程式,接著輸入curl -X GET localhost:8000/就會看到 {message: get called} 的訊息了。

階段三: 設計 Web API

func main() {
    router := mux.NewRouter()
    api := router.PathPrefix("/api/v1").Subrouter()
    api.HandleFunc("/", get).Methods(http.MethodGet)
    err := http.ListenAndServe(":8000", router)
    if err != nil {
        panic(err) // 如果有錯誤就終止程式
    }
    fmt.Println("The port 8000 is successfully connected")
}

假如在我的server上有很多支API路徑,我希望透過不同的namespace來做管理。透過 mux 利用 PathPrefix("/api/v1").Subrouter(),篩選符合路徑的請求並做路徑分流。現在要輸入curl -X GET localhost:8000/api/v1/才會看到 {message: get called} 的訊息。參考文件

之後可以加入其它像是POST、PUT、DELETE的動作來做不同的路由處裡。
完整範例參考

筆記參考

Mux官方文件


#Go http #Gorilla Mux #REST API #Go Router







Related Posts

The introduction and difference between class component and function component in React

The introduction and difference between class component and function component in React

JS30 Day 18 筆記

JS30 Day 18 筆記

十分鐘、五步驟,SVG 動起來!

十分鐘、五步驟,SVG 動起來!


Comments